<template>
  <div :class="circleClass" :style="circleStyle">
    <svg :style="svgStyle">
      <defs v-show="showDefs">
        <linearGradient :id="id" x1="100%" y1="0%" x2="0%" y2="0%">
          <stop offset="0%" :stop-color="strokeColor[0]" />
          <stop offset="100%" :stop-color="strokeColor[1]" />
        </linearGradient>
      </defs>
      <!-- cx cy r 可能为svg circle独有，不能放在computed中，浏览器识别不出来 -->
      <circle :style="outStyle" :cx="this.size/2" :cy="this.size/2" :r="getCircleR" />
      <circle
        :style="innerStyle"
        :cx="this.size/2"
        :cy="this.size/2"
        :r="getCircleR"
        :stroke-dasharray="[getCircleOffset,getCirclePerimeter]"
      />
    </svg>
    <div :class="circleGroupClass" :style="circleGroupStyle">
      <div v-show="!isShowIcon">
        <slot>
          <span :style="{fontSize:fontSize,}">{{percent}}%</span>
        </slot>
      </div>
      <i :class="circleIconClass" :style="circleIconStyle" v-show="isShowIcon"></i>
    </div>
  </div>
</template>
<script>
import { randomStr } from "utils/random";
export default {
  name: "BCircle",
  props: {
    percent: {
      type: Number,
      default: 10,
    },
    size: {
      type: Number,
      default: 150,
    },
    /**进度环宽度 */
    strokeWidth: {
      type: Number,
      default: 10,
    },
    strokeColor: {
      type: [String, Array],
      default: "var(--primary)",
    },
    /**进度条背景颜色 */
    baseColor: {
      type: String,
      default: "#eaeef2",
    },
    fontSize: {
      type: String,
      default: "24px",
    },
    iconSize: {
      type: String,
      default: "",
    },
    dashboard: {
      type: Boolean,
      default: false,
    },
    showIcon: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      id: "Gradient" + randomStr(), //多个组件同时存在时，id必须不同才能获取到渐变色
    };
  },
  computed: {
    circleClass() {
      return ["vbestui-circle"];
    },
    circleStyle() {
      return {
        width: `${this.size}px`,
        height: this.dashboard ? `${this.size * 0.75}px` : `${this.size}px`,
        overflow: this.dashboard ? "hidden" : "",
      };
    },
    svgStyle() {
      return {
        width: `${this.size}px`,
        height: `${this.size}px`,
        transform: this.dashboard ? "rotate(150deg)" : "rotate(90deg)", //改变加载开始方向
      };
    },
    outStyle() {
      return {
        // cx: `${this.size / 2}`,
        // cy: `${this.size / 2}`,
        // r: this.getCircleR,
        fill: "none",
        stroke: `${this.baseColor}`,
        strokeWidth: `${this.strokeWidth}px`,
      };
    },
    innerStyle() {
      return {
        // cx: `${this.size / 2}`,
        // cy: `${this.size / 2}`,
        // r: this.getCircleR,
        fill: "none",
        stroke: this.getStrokeColor,
        strokeWidth: `${this.strokeWidth}px`,
        strokeLinecap: "round",
        transition: `all .4s var(--animation-ease-out)`,
      };
    },
    circleGroupClass() {
      return ["vbestui-circle-group"];
    },
    circleGroupStyle() {
      return {
        width: `${this.getQuadrateL}px`,
        height: `${this.getQuadrateL}px`,
        paddingTop: this.dashboard ? `${this.size * 0.25}px` : "", //仪表盘模式时修改文字位置
      };
    },
    circleIconClass() {
      return ["vbestui-iconfont icon-dui vbestui-circle-icon"];
    },
    circleIconStyle() {
      return { fontSize: this.iconSize };
    },
    /**计算偏移量 */
    getCircleOffset() {
      return (this.percent / 100) * this.getCirclePerimeter;
    },
    /**计算圆的周长 */
    getCirclePerimeter() {
      let per = 2 * Math.PI * this.getCircleR;
      if (this.dashboard) per = (per * 2) / 3;
      return per;
    },
    /**计算圆的半径 */
    getCircleR() {
      return (this.size - this.strokeWidth) / 2;
    },
    /**计算园内正方形边长 */
    getQuadrateL() {
      return Math.floor(this.getCircleR * Math.SQRT2);
    },
    getStrokeColor() {
      let color = this.strokeColor;
      if (typeof this.strokeColor != "string") {
        color = `url(#${this.id})`;
      }
      if (this.isShowIcon) color = "var(--success)";
      return color;
    },
    showDefs() {
      return typeof this.strokeColor != "string";
    },
    isInnerShow() {
      return this.percent != 0;
    },
    isShowIcon() {
      return this.percent == 100 && this.showIcon;
    },
  },
};
</script>